package com.zz.admin.userManagement.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zz.admin.auth.enums.BaseAuthExceptionEnum;
import com.zz.admin.userManagement.dto.UserDto;
import com.zz.admin.userManagement.dto.UserRoleMenuDto;
import com.zz.admin.userManagement.entity.User;
import com.zz.admin.userManagement.mapper.UserMapper;
import com.zz.admin.userManagement.service.UserService;
import com.zz.common.base.dto.PageListResultDto;
import com.zz.common.base.enums.BaseExceptionEnum;
import com.zz.common.base.param.QueryParam;
import com.zz.common.constants.BaseConstant;
import com.zz.common.exception.ExceptionFactory;
import com.zz.common.utils.common.UUIDGenerator;
import com.zz.common.utils.mapper.BeanMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;


/**
 * 用户表 服务实现类
 *
 * @author zhang.lei
 * @since 2025-04-08 19:52:27
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Override
    public PageListResultDto<UserDto> queryWithPage(UserDto userDto, QueryParam queryParam) {
        Page<User> page = new Page<>(queryParam.getPageNum(), queryParam.getPageSize());
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        List<User> users = userMapper.selectList(page, wrapper);
        List<UserDto> userDtos = BeanMapper.mapList(users, User.class, UserDto.class);
        return new PageListResultDto<>((int) page.getCurrent(), (int) page.getTotal(), queryParam.getPageSize(), userDtos);
    }

    @Override
    public List<UserDto> queryWithNoPage(UserDto userDto) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        List<User> users = userMapper.selectList(wrapper);
        return BeanMapper.mapList(users, User.class, UserDto.class);
    }

    @Override
    public UserDto queryById(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }
        User user = userMapper.selectById(id);
        if (user == null || BaseConstant.YES.equals(user.getDelFlag())) {
            return null;
        }
        return BeanMapper.map(user, UserDto.class);
    }

    @Override
    public UserDto getAdminUser() {
        String username = "admin";
        QueryWrapper<User> query = new QueryWrapper<>();
        query.eq("user_name", username)
                .eq("del_flag", BaseConstant.NO) // 假设DelFlag是枚举类型
                .orderByDesc("create_date")
                .last("LIMIT 1"); // 数据库层面限制结果集

        User user = userMapper.selectOne(query);
        if (user == null) {
            return null;
        }
        return BeanMapper.map(user, UserDto.class);
    }

    @Override
    public UserDto queryByLoginAccount(String loginAccount) {
        if (StringUtils.isBlank(loginAccount)) {
            return null;
        }
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("login_account", loginAccount).eq("del_flag", BaseConstant.NO);
        List<User> users = userMapper.selectList(userQueryWrapper);
        if (CollectionUtils.isEmpty(users)) {
            return null;
        } else if (users.size() > 1) {
            throw ExceptionFactory.createBaseException(BaseAuthExceptionEnum.BASE_ERROR, "登录名重复，请查证");
        }
        return BeanMapper.map(users.get(0), UserDto.class);
    }

    @Override
    public List<UserDto> queryByIds(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        List<User> users = userMapper.selectByIds(ids);
        if (CollectionUtils.isEmpty(users)) {
            return new ArrayList<>();
        }
        return BeanMapper.mapList(users, User.class, UserDto.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserDto save(UserDto userDto) {
        // 根据业务修改
        return insert(userDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<UserDto> saveBatch(List<UserDto> userDtos) {
        // 根据业务修改
        return insertList(userDtos);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserDto modify(UserDto userDto) {
        // 根据业务修改
        updateById(userDto);
        return userDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<UserDto> modifyBatch(List<UserDto> userDtos) {
        // 根据业务修改
        return updateList(userDtos);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        // 根据业务修改
        UserDto userDto = new UserDto();
        userDto.setUserId(id);
        deleteById(userDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteBatch(List<String> ids) {
        // 根据业务修改
        deleteByPrimaryKeys(ids);
    }

    @Override
    public UserDto insert(UserDto userDto) {
        userDto.setUserId(UUIDGenerator.generateUUID());
        userDto.setDelFlag(BaseConstant.NO);
        User entity = BeanMapper.map(userDto, User.class);
        userMapper.insert(entity);
        return userDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public UserDto insertWithId(UserDto userDto) {
        if (StringUtils.isBlank(userDto.getUserId())) {
            userDto.setUserId(UUIDGenerator.generateUUID());
        }
        userDto.setDelFlag(BaseConstant.NO);
        User entity = BeanMapper.map(userDto, User.class);
        userMapper.insert(entity);
        return userDto;
    }

    private List<UserDto> insertList(List<UserDto> userDtos) {
        if (CollectionUtils.isEmpty(userDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "批量插入时，参数不能为空");
        }
        List<User> insertList = new ArrayList<>();
        for (UserDto userDto : userDtos) {
            if (StringUtils.isBlank(userDto.getUserId())) {
                userDto.setUserId(UUIDGenerator.generateUUID());
            }
            userDto.setDelFlag(BaseConstant.NO);
            insertList.add(BeanMapper.map(userDto, User.class));
        }
        userMapper.insert(insertList, 1000);
        return userDtos;
    }

    private List<UserDto> updateList(List<UserDto> userDtos) {
        if (CollectionUtils.isEmpty(userDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "批量更新时，参数不能为空");
        }
        for (UserDto userDto : userDtos) {
            if (StringUtils.isBlank(userDto.getUserId())) {
                throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "批量更新时，主键不能为空");
            }
        }
        List<User> userList = BeanMapper.mapList(userDtos, UserDto.class, User.class);
        userMapper.updateById(userList, 1000);
        return userDtos;
    }

    @Transactional(rollbackFor = Exception.class)
    public int updateById(UserDto userDto) {
        if (StringUtils.isBlank(userDto.getUserId())) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "更新时，主键不能为空");
        }
        User entity = BeanMapper.map(userDto, User.class);
        return userMapper.updateById(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public int trueDeleteById(String id) {
        return userMapper.deleteById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    public int deleteById(UserDto userDto) {
        userDto.setDelFlag(BaseConstant.YES);
        return updateById(userDto);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteByPrimaryKeys(List<String> ids) {
        List<UserDto> userDtos = new ArrayList<>();
        for (String id : ids) {
            UserDto userDto = new UserDto();
            userDto.setUserId(id);
            userDto.setDelFlag(BaseConstant.YES);
            userDtos.add(userDto);
        }
        updateList(userDtos);
    }

    @Override
    public List<UserRoleMenuDto> queryRoleAndMenuByUserId(String userId) {
        if (org.apache.commons.lang3.StringUtils.isBlank(userId)) {
            return new ArrayList<>();
        }
        return userMapper.queryRoleAndMenuByUserId(userId);
    }

    @Override
    public UserDto insertFromThirdParty(String thirdPartyUserId, String thirdPartyUserCode, String thirdPartyUserName) {
        User user = queryByThirdPartyUserId(thirdPartyUserId);
        if (ObjectUtil.isNull(user)) {
            // 组装第三方用户信息
            UserDto userDto = getThirdPartyUserDto(thirdPartyUserId, thirdPartyUserCode, thirdPartyUserName);
            return insert(userDto);
        }
        return BeanMapper.map(user, UserDto.class);
    }

    private UserDto getThirdPartyUserDto(String thirdPartyUserId, String thirdPartyUserCode, String thirdPartyUserName) {
        UserDto userDto = new UserDto();
        userDto.setThirdPartyId(thirdPartyUserId);
        userDto.setUserCode(thirdPartyUserCode);
        userDto.setUserName(thirdPartyUserName);
        // todo:

        return userDto;
    }

    private User queryByThirdPartyUserId(String thirdPartyUserId) {
        QueryWrapper<User> query = new QueryWrapper<>();
        query.eq("third_party_id", thirdPartyUserId)
                .eq("del_flag", BaseConstant.NO);
        return userMapper.selectOne(query);
    }
}
